<!-- SpatiotemporalAlignment.vue -->
<template>
  <div class="spatiotemporal-container">
    <div class="header">
      <h2 class="panel-title"><i class="icon-time"></i> 时空数据对齐监控</h2>
      <el-button class="sync-btn" type="primary" size="small" @click="syncTime">
        <el-icon><Refresh /></el-icon> 同步时间
      </el-button>
    </div>
    <div class="timeline-controls">
      <el-slider v-model="timeRange" range :min="0" :max="100" :marks="marks" />
    </div>
    <div class="timeline-wrapper">
      <div ref="timelineChart" class="timeline-chart"></div>
    </div>
    <div class="status-grid">
      <div class="status-row" v-for="(device, idx) in devices" :key="device.id">
        <div class="device-name">{{ device.name }}</div>
        <div class="status-bars">
          <div v-for="segment in device.segments"
               :key="segment.id"
               class="status-bar"
               :class="segment.status"
               :style="{ width: segment.width + '%' }"></div>
        </div>
        <div class="sync-status" :class="device.syncStatus">
          <el-tooltip effect="dark" :content="device.syncTip" placement="top">
            <span v-if="device.syncStatus === 'aligned'"><el-icon><SuccessFilled /></el-icon> 已对齐</span>
            <span v-else-if="device.syncStatus === 'lagging'"><el-icon><WarningFilled /></el-icon> 滞后 {{device.lag/1000}}s</span>
            <span v-else><el-icon><CircleCloseFilled /></el-icon> 未同步</span>
          </el-tooltip>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { Refresh, SuccessFilled, WarningFilled, CircleCloseFilled } from '@element-plus/icons-vue';
import {ElButton, ElIcon, ElSlider, ElTooltip} from "element-plus";

export default defineComponent({
  name: 'SpatiotemporalAlignment',
  components: {ElButton, ElSlider, ElIcon, ElTooltip, Refresh, SuccessFilled, WarningFilled, CircleCloseFilled },
  setup() {
    const timelineChart = ref(null);
    let chartInstance = null;
    const timeRange = ref([30, 70]);
    const marks = ref({
      0: '00:00',
      25: '06:00',
      50: '12:00',
      75: '18:00',
      100: '24:00'
    });

    const devices = ref([
      {
        id: 'device-1',
        name: 'GPS接收器-A',
        segments: [
          { id: 's1', status: 'aligned', width: 60 },
          { id: 's2', status: 'lagging', width: 15 },
          { id: 's3', status: 'aligned', width: 25 }
        ],
        syncStatus: 'lagging',
        syncTip: '设备时间滞后约3.2秒',
        lag: 3200
      },
      {
        id: 'device-2',
        name: '北斗终端-B',
        segments: [
          { id: 's4', status: 'aligned', width: 85 },
          { id: 's5', status: 'not-synced', width: 15 }
        ],
        syncStatus: 'not-synced',
        syncTip: '设备尚未进行时间同步',
        lag: 0
      },
      {
        id: 'device-3',
        name: '同步服务器',
        segments: [{ id: 's6', status: 'aligned', width: 100 }],
        syncStatus: 'aligned',
        syncTip: '时间已同步至UTC标准',
        lag: 0
      },
      {
        id: 'device-4',
        name: '传感器网络',
        segments: [
          { id: 's7', status: 'lagging', width: 20 },
          { id: 's8', status: 'aligned', width: 80 }
        ],
        syncStatus: 'aligned',
        syncTip: '时间同步在正常范围内',
        lag: 500
      }
    ]);

    const initChart = () => {
      if (timelineChart.value) {
        chartInstance = echarts.init(timelineChart.value, 'dark');
        const option = {
          backgroundColor: 'transparent',
          tooltip: {
            trigger: 'axis'
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            top: '5%',
            containLabel: true
          },
          xAxis: {
            type: 'time',
            axisLine: { lineStyle: { color: '#5a7cc9' } },
            splitLine: { show: false },
            axisLabel: { color: '#a0bff0' }
          },
          yAxis: {
            type: 'value',
            min: -0.5,
            max: 3.5,
            interval: 1,
            data: ['GPS接收器', '北斗终端', '同步服务器', '传感器网络'],
            inverse: true,
            axisLine: { show: false },
            axisTick: { show: false },
            axisLabel: { color: '#c2d4ff', margin: 15 }
          },
          visualMap: {
            top: 10,
            right: 10,
            pieces: [
              { gt: -0.5, lte: 0.5, color: '#2ecc71' },
              { gt: 0.5, lte: 1.5, color: '#f39c12' },
              { gt: 1.5, lte: 2.5, color: '#3498db' },
              { gt: 2.5, lte: 3.5, color: '#9b59b6' }
            ],
            dimension: 0,
            outOfRange: { color: '#999' },
            show: false
          },
          series: [
            {
              name: '时间对齐状态',
              type: 'scatter',
              symbolSize: 14,
              data: [
                [new Date(2025, 7, 5, 8, 14, 20), 0, 'GPS接收器-A'],
                [new Date(2025, 7, 5, 10, 22, 15), 1, '北斗终端-B'],
                [new Date(2025, 7, 5, 12, 45, 30), 2, '同步服务器'],
                [new Date(2025, 7, 5, 15, 8, 42), 3, '传感器网络'],
                [new Date(2025, 7, 5, 16, 33, 57), 0, 'GPS接收器-A'],
                [new Date(2025, 7, 5, 17, 55, 9), 1, '北斗终端-B'],
                [new Date(2025, 7, 5, 19, 21, 3), 3, '传感器网络']
              ],
              itemStyle: {
                color: function(params) {
                  const colors = ['#2ecc71', '#f39c12', '#3498db', '#9b59b6'];
                  return colors[Math.floor(params.data[1])];
                }
              }
            },
            {
              name: '实时位置',
              type: 'line',
              data: [
                [new Date(2025, 7, 5, 8, 0, 0), 0],
                [new Date(2025, 7, 5, 12, 0, 0), 1],
                [new Date(2025, 7, 5, 15, 15, 0), 2],
                [new Date(2025, 7, 5, 18, 0, 0), 3]
              ],
              symbol: 'path://M0,0 L10,0 L10,20 L0,20 L0,0',
              symbolSize: 20,
              lineStyle: {
                color: '#ff6b6b',
                width: 2,
                type: 'dashed'
              },
              markLine: {
                symbol: 'none',
                lineStyle: { color: '#ff6b6b', type: 'solid', width: 1 },
                data: [{ xAxis: new Date(2025, 7, 5, 15, 15, 0) }]
              }
            }
          ]
        };

        chartInstance.setOption(option);

        // 窗口大小变化时重新调整图表
        window.addEventListener('resize', () => {
          if (chartInstance) chartInstance.resize();
        });
      }
    };

    const syncTime = () => {
      // 简单模拟同步操作
      devices.value.forEach(device => {
        if (device.syncStatus !== 'aligned') {
          device.syncStatus = 'aligned';
          device.lag = Math.floor(Math.random() * 300);
          device.syncTip = `时间同步在正常范围内 (滞后 ${device.lag}ms)`;

          // 重置段状态
          device.segments.forEach(segment => {
            segment.status = 'aligned';
          });
        }
      });

      // 添加提示效果
      ElMessage.success({
        message: '系统时间已同步至UTC基准',
        duration: 2000
      });
    };

    onMounted(() => {
      initChart();
    });

    onBeforeUnmount(() => {
      if (chartInstance) {
        window.removeEventListener('resize', () => chartInstance.resize());
        chartInstance.dispose();
      }
    });

    return {
      timelineChart,
      timeRange,
      marks,
      devices,
      syncTime
    };
  }
});
</script>

<style scoped>
.spatiotemporal-container {
  display: flex;
  flex-direction: column;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.8vh 0.5vw 1.5vh;
  border-bottom: 1px solid rgba(97, 130, 234, 0.2);
}

.panel-title {
  margin: 0;
  font-size: 1vw;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
}

.panel-title i {
  display: inline-block;
  width: 24px;
  height: 24px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23f39c12' d='M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67V7z'/%3E%3C/svg%3E");
}

.sync-btn {
  background: linear-gradient(90deg, #3a78c9, #1a56a0);
  border: none;
  border-radius: 4px;
  padding: 6px 14px;
}

.timeline-controls {
  padding: 1vh 0.5vw;
}

.timeline-wrapper {
  height: 25vh;
  position: relative;
  margin: 0.5vh 0 1.5vh;
}

.timeline-chart {
  width: 100%;
  height: 100%;
}

.status-grid {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.8vh;
  padding: 1.2vh 0.5vw;
  margin-top: 1vh;
  background: rgba(12, 20, 40, 0.4);
  border-radius: 8px;
  border: 1px solid rgba(64, 100, 200, 0.2);
}

.status-row {
  display: flex;
  align-items: center;
  height: 5.5vh;
  gap: 0.8vw;
}

.device-name {
  width: 14vw;
  font-weight: 500;
  font-size: 0.95rem;
  color: #c0d1ff;
}

.status-bars {
  flex: 1;
  display: flex;
  height: 70%;
  background: rgba(23, 30, 60, 0.7);
  border-radius: 4px;
  overflow: hidden;
}

.status-bar {
  height: 100%;
  transition: width 0.5s ease;
}

.status-bar.aligned {
  background: linear-gradient(90deg, rgba(46, 204, 113, 0.7), rgba(46, 204, 113, 0.9));
}

.status-bar.lagging {
  background: linear-gradient(90deg, rgba(243, 156, 18, 0.7), rgba(243, 156, 18, 0.9));
}

.status-bar.not-synced {
  background: linear-gradient(90deg, rgba(231, 76, 60, 0.7), rgba(231, 76, 60, 0.9));
}

.sync-status {
  width: 10vw;
  text-align: right;
  font-size: 0.85rem;
  font-weight: 500;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.5vw;
}

.sync-status.aligned {
  color: #2ecc71;
}

.sync-status.lagging {
  color: #f39c12;
}

.sync-status.not-synced {
  color: #e74c3c;
}
</style>